package com.linh.location;

import java.util.ArrayList;

import org.apache.http.client.methods.HttpGet;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class LocationActivity extends MapActivity {
	static final String BUS_STOP_SEARCH_ACTION = "busStopSearch";
	LocationManager locationManager;
	Location currentLocation;
	MapView mapView;
	MapController mapController;
	TextView textView;
	PointOverlay pointOverlay;
	BusStopOverlay busStopOverlay;
	String urlPrefix;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_location);
		mapView = (MapView) findViewById(R.id.map);

		textView = (TextView) findViewById(R.id.text);
		mapController = mapView.getController();
		mapController.setZoom(17);
		Drawable pointIcon = this.getResources().getDrawable(
				R.drawable.ic_launcher);
		Drawable busStopIcon = this.getResources().getDrawable(
				R.drawable.ic_bus_stop);
		urlPrefix = getResources().getString(R.string.rfl_bus_api_url_prefix);

		pointOverlay = new PointOverlay(pointIcon);
		busStopOverlay = new BusStopOverlay(this, busStopIcon);
		mapView.getOverlays().add(pointOverlay);
		mapView.getOverlays().add(busStopOverlay);
		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		recover();

	}

	@Override
	protected void onStart() {

		super.onStart();
		if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			// ask user to enable GPS
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Location Manager");
			builder.setMessage("Please enable GPS!");
			builder.setPositiveButton("Yes",
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// launch settings, allowing user to make a change
							Intent i = new Intent(
									Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							startActivity(i);

						}
					});
			builder.setNegativeButton("No",
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// No location service, no activity
							finish();

						}
					});
			builder.create().show();
		}
		// get a cached location if exists
		currentLocation = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		updateDisplay();

		// register for updates
		int minTime = 1000;
		float minDistance = 0;
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				minTime, minDistance, listener);
		registerReceiver(busStopSearchReceiver, new IntentFilter(
				BUS_STOP_SEARCH_ACTION));
	}

	// update location on the text view
	private void updateDisplay() {
		double lat, lng;
		if (currentLocation == null) {
			// london
			lat = 51.5171;
			lng = -0.1062;

		} else {
			lat = currentLocation.getLatitude();
			lng = currentLocation.getLongitude();
		}
		GeoPoint geoPoint = new GeoPoint((int) (lat * 1000000),
				(int) (lng * 1000000));
		pointOverlay.setPoint(geoPoint);

		mapController.setCenter(geoPoint);

		textView.setText(String.format("Longitude %.2f, Latitude %.2f", lng,
				lat));
		queryForBusStops(lat, lng);
	}

	boolean recover() {

		// check if user accessed schedule
		String lastStop = getSharedPreferences(
				BusScheduleActivity.class.getSimpleName(), MODE_PRIVATE)
				.getString(BusScheduleActivity.LAST_BUS_STOP, null);
		if (lastStop != null) {

			// same location, recover last bus stop
			Intent intent = new Intent();
			intent.setClassName(this, BusScheduleActivity.class.getName());
			intent.putExtra(BusScheduleActivity.RECOVER_ACTION, lastStop);
			this.startActivity(intent);
			return true;

		}

		return false;
	}

	protected void queryForBusStops(double lat, double lng) {

		String placeUrl = BusUrl.getQueryUrl(urlPrefix, lng, lat);
		Log.i(getLocalClassName(), placeUrl);
		PlaceFindingTask task = new PlaceFindingTask(this,
				BUS_STOP_SEARCH_ACTION);
		task.execute(new HttpGet(placeUrl));
	}

	@Override
	protected void onStop() {

		super.onPause();
		locationManager.removeUpdates(listener);
		unregisterReceiver(busStopSearchReceiver);
	}

	private LocationListener listener = new LocationListener() {

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {

		}

		@Override
		public void onProviderEnabled(String provider) {

		}

		@Override
		public void onProviderDisabled(String provider) {

		}

		@Override
		public void onLocationChanged(Location location) {
			currentLocation = location;
			updateDisplay();

		}
	};

	@Override
	protected boolean isRouteDisplayed() {

		return true;
	}

	private BroadcastReceiver busStopSearchReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context paramContext, Intent paramIntent) {
			@SuppressWarnings("unchecked")
			ArrayList<BusStop> busStops = (ArrayList<BusStop>) paramIntent
					.getSerializableExtra(PlaceFindingTask.PLACE_FINDING_RESULT);
			if (busStops != null) {
				textView.setText("Number of bus stops found: "
						+ busStops.size());
				busStopOverlay.setBusStops(busStops);
			}

		}

	};
}
